home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 February: Tool Chest / Apple Developer CD Series Tool Chest February 1996 (Apple Computer)(1996).iso / Sample Code / AOCE Sample Code / PowerTalk Access Modules / Sample SMSAM / SampleSMSAM Source / BuildingBlocks / DialogWindow.cp < prev    next >
Encoding:
Text File  |  1995-07-28  |  14.7 KB  |  595 lines  |  [TEXT/KAHL]

  1. /*
  2.     File:        DialogWindow.cp
  3.  
  4.     Copyright:    © 1991-1994 by Apple Computer, Inc.
  5.                 All rights reserved.
  6.  
  7.     Part of the AOCE Sample SMSAM Package.  Consult the license
  8.     which came with this software for your specific legal rights.
  9.  
  10. */
  11.  
  12.  
  13.  
  14. #ifndef __BLJSTANDARDINCLUDES__
  15. #include "BLJStandardIncludes.h"
  16. #endif
  17.  
  18. #ifndef __DIALOGWINDOW__
  19. #include "DialogWindow.h"
  20. #endif
  21.  
  22. #ifndef __OBJECTLIST__
  23. #include "ObjectList.h"
  24. #endif
  25.  
  26. /***********************************|****************************************/
  27.  
  28. pascal OSErr SetDialogDefaultItem ( DialogPtr dP, short item ) = { 0x303c, 0x0304, 0xaa68 };
  29. pascal OSErr SetDialogCancelItem ( DialogPtr dP, short item ) = { 0x303c, 0x0305, 0xaa68 };
  30.  
  31. /***********************************|****************************************/
  32.  
  33. DeclareList(TDialogWindow,TDialogWindowList);
  34. ImplementList(TDialogWindow,TDialogWindowList,true);
  35.  
  36. TDialogWindowList    gTDialogWindowList;
  37.  
  38. /***********************************|****************************************/
  39.  
  40. Boolean TDialogWindow::HandleAnEvent ( EventRecord& event )
  41. {
  42.     Boolean result = false;
  43.     
  44.     for ( unsigned short i = 1; i <= gTDialogWindowList.Count(); ++i ) {
  45.         TDialogWindow * dialogWindow = gTDialogWindowList.Get ( i );
  46.         
  47.         if ( dialogWindow )
  48.             if ( dialogWindow->HandleEvent ( event ) )
  49.             {
  50.                 result = true;
  51.                 break;
  52.             }
  53.     }
  54.     
  55.     return result;
  56. }
  57.  
  58. /***********************************|****************************************/
  59.  
  60. typedef struct WindowInfoRecord {
  61.     Boolean            visible;
  62.     Rect            location;
  63. } WindowInfoRecord, *WindowInfoPtr, **WindowInfoHandle;
  64.  
  65. /***********************************|****************************************/
  66.  
  67. extern short gBovineServerPrefsFile;
  68.  
  69. /***********************************|****************************************/
  70.  
  71. Handle Get1ResourceFromFile ( OSType resType, short resID, short resFile )
  72. {
  73.     short savedResFile = CurResFile ();
  74.     UseResFile ( resFile );
  75.     Handle result = Get1Resource ( resType, resID );
  76.     UseResFile ( savedResFile );
  77.  
  78.     return result;
  79. }
  80.  
  81. /***********************************|****************************************/
  82.  
  83. Boolean GetDefaultWindowInformation ( short dialogID, Boolean& visible, Rect & screenRect )
  84. {
  85.     WindowInfoHandle infoH = (WindowInfoHandle) Get1ResourceFromFile ( 'WINF', dialogID, gBovineServerPrefsFile );
  86.     
  87.     if ( infoH && *infoH )
  88.     {
  89.         visible = (**infoH).visible;
  90.         screenRect = (**infoH).location;
  91.         
  92.         ReleaseResource ( (Handle) infoH );
  93.         return true;
  94.     }
  95.     
  96.     return false;
  97. }
  98.  
  99. /***********************************|****************************************/
  100.  
  101. void LocalToGlobalRect ( const Rect& rect, Rect & result )
  102. {    
  103.     result = rect;
  104.     LocalToGlobal ( (Point *) & result.top );
  105.     LocalToGlobal ( (Point *) & result.bottom );
  106. }
  107.  
  108. /***********************************|****************************************
  109.  *
  110.  *    SetDefaultWindowInformation ( WindowPtr dP, short dialogID )
  111.  *
  112.  *    Save the location and other window state for the given window in a
  113.  *    resource of type 'WINF' with the resource id dialogID in the
  114.  *    application's preferences file.
  115.  *
  116.  ***********************************|***************************************/
  117.  
  118. Boolean SetDefaultWindowInformation ( WindowPtr dP, short dialogID  )
  119. {
  120.     WindowInfoHandle infoH = (WindowInfoHandle) Get1ResourceFromFile ( 'WINF', dialogID, gBovineServerPrefsFile );
  121.     GrafPtr savedPort;
  122.     short savedResFile = CurResFile();
  123.  
  124.     UseResFile(gBovineServerPrefsFile);
  125.     GetPort ( & savedPort );
  126.     SetPort ( dP );
  127.     
  128.     if ( !infoH ) {
  129.         infoH = (WindowInfoHandle) NewHandleClear ( sizeof( **infoH ) );
  130.  
  131.         AddResource ( (Handle) infoH, 'WINF', dialogID, "\p");
  132.     }
  133.             
  134.     if ( infoH && *infoH )
  135.     {
  136.         (**infoH).visible = ((WindowPeek) dP)->visible;
  137.         LocalToGlobalRect ( dP->portRect, (**infoH).location );
  138.         
  139.         ChangedResource ( (Handle) infoH );
  140.         WriteResource ( (Handle) infoH );
  141.         ReleaseResource ( (Handle) infoH);
  142.         
  143.         return true;
  144.     }
  145.     
  146.     UseResFile (savedResFile);
  147.     SetPort ( savedPort );
  148.     return false;
  149. }
  150.  
  151. /***********************************|****************************************
  152.  *
  153.  *    RectOnScreen ( const Rect & where )
  154.  *
  155.  *    Return true if the given rectangle is "on" the screen -- meaning that
  156.  *    no part of the rectangle is not on a visible screen.
  157.  *
  158.  ***********************************|***************************************/
  159.  
  160. Boolean RectOnScreen ( const Rect& where )
  161. {
  162.     RgnHandle rectRgn = NewRgn();
  163.     RgnHandle intersectionRgn = NewRgn();
  164.     
  165.     RectRgn ( rectRgn, &where );
  166.     
  167.     SectRgn ( rectRgn, GetGrayRgn(), intersectionRgn );
  168.     
  169.     Boolean result = EqualRgn ( rectRgn, intersectionRgn );
  170.     
  171.     DisposeRgn ( rectRgn );
  172.     DisposeRgn ( intersectionRgn );
  173.  
  174.     return result;
  175. }
  176.  
  177. /***********************************|****************************************
  178.  *
  179.  *    IsModalWindow ( WindowPtr window )
  180.  *
  181.  *    Return true if this type of window is 'modal'; false otherwise.
  182.  *
  183.  ***********************************|***************************************/
  184.  
  185. static Boolean IsModalWindow ( WindowPtr windowP )
  186. {    
  187.     Boolean result = false;
  188.     
  189.     if ( windowP )
  190.     {    short windowKind = ((WindowPeek) windowP)->windowKind;
  191.     
  192.         if ( ( windowKind == dBoxProc ) || ( windowKind == 5 ) )
  193.             result = true;
  194.     }
  195.     
  196.     return result;
  197. }
  198.  
  199. /***********************************|****************************************/
  200.  
  201. TDialogWindow::TDialogWindow ( short dialogID, short stringsSTRPoundID ) :
  202.     fDialogID ( dialogID ),
  203.     fStringsSTRPoundID ( stringsSTRPoundID ),
  204.     fStringItemsCount ( 0 ),
  205.     fButtonItemsCount ( 0 ),
  206.     fUserItemsCount ( 0 ),
  207.     fPosedModally ( false )
  208. {
  209.     fDialogWindow = GetNewDialog ( dialogID, nil, (WindowPtr) -1 );
  210.  
  211.     if ( !fDialogWindow )
  212.         return;
  213.     
  214.     //    Try to get the 'default' location for this window from the preferences.
  215.     Boolean visible;
  216.     Rect where;
  217.     if ( GetDefaultWindowInformation ( fDialogID, visible, where ) && RectOnScreen ( where ) )
  218.     {
  219.         MoveWindow ( fDialogWindow, where.left, where.top, false );
  220.     }
  221.     else
  222.         visible = true;
  223.     
  224.     //    Now, update the arrays of where each item is.    
  225.     short itemCount = CountDITL ( fDialogWindow );
  226.     for ( short index = 1; index <= itemCount; ++index ) {
  227.         short itemKind;
  228.         Handle itemHandle;
  229.         Rect itemRect;
  230.         
  231.         GetDItem ( fDialogWindow, index, & itemKind, & itemHandle, & itemRect );
  232.         
  233.         switch ( itemKind )
  234.         {
  235.             case statText:
  236.             case editText:
  237.                 fStringItemNumbers [ ++ fStringItemsCount ] = index;
  238.                 break;
  239.                 
  240.             case ctrlItem + btnCtrl:
  241.                 fButtonItemNumbers [ ++ fButtonItemsCount ] = index;
  242.                 break;
  243.                 
  244.             case userItem:
  245.                 fUserItemNumbers [ ++ fUserItemsCount ] = index;
  246.                 fUserItemRect [ fUserItemsCount ] = itemRect;
  247.                 break;
  248.         }
  249.     }            
  250.     
  251.     //    If the first item is a button, then set it as the "default" item.  Set the second
  252.     //    item as the cancel item if it's a button.
  253.     if ( ( fButtonItemsCount >= 1 ) && ( fButtonItemNumbers[1] == 1 ) )
  254.     {
  255.         SetDialogDefaultItem ( fDialogWindow, 1 );
  256.  
  257.         if ( ( fButtonItemsCount >= 2 ) && ( fButtonItemNumbers[2] == 1 ) )
  258.         {
  259.             SetDialogCancelItem ( fDialogWindow, 2 );
  260.         }
  261.     }
  262.         
  263.     gTDialogWindowList.Append ( this );
  264.     
  265.     if ( visible )
  266.         ::ShowWindow ( fDialogWindow );
  267.     
  268.     //    If it's a modal window, pull it to the front.
  269.     if ( IsModalWindow ( fDialogWindow ) )
  270.         ::SelectWindow ( fDialogWindow );
  271. }
  272.  
  273. /***********************************|****************************************/
  274.  
  275. TDialogWindow::~TDialogWindow ( )
  276. {
  277.     gTDialogWindowList.Remove ( this );
  278.     
  279.     DisposeDialog ( fDialogWindow );
  280. }
  281.  
  282. /***********************************|****************************************/
  283.  
  284. void TDialogWindow::ShowWindow ()
  285. {
  286.     //    If there's another dialog window frontmost, then wait for it to go away.
  287.     if ( FrontWindow() && ( ((WindowPeek) FrontWindow())->windowKind == dialogKind ) )
  288.     {
  289.         TYield();
  290.     }
  291.     
  292.     if ( fDialogWindow ) {
  293.         ::ShowWindow ( fDialogWindow );
  294.         SetPort ( fDialogWindow );
  295.         SetDefaultWindowInformation ( fDialogWindow, fDialogID );
  296.     }
  297. }
  298.  
  299. /***********************************|****************************************/
  300.  
  301. void TDialogWindow::SelectWindow ()
  302. {
  303. /*        If there's another dialog window frontmost, then wait for it to go away.*/
  304. /*    if ( FrontWindow() && ( ((WindowPeek) FrontWindow())->windowKind == dialogKind ) )*/
  305. /*    {*/
  306. /*        TYield();*/
  307. /*    }*/
  308.     
  309.     if ( fDialogWindow ) {
  310.         ::ShowWindow ( fDialogWindow );
  311.         ::SelectWindow ( fDialogWindow );
  312.         SetDefaultWindowInformation ( fDialogWindow, fDialogID );
  313.     }
  314. }
  315.  
  316. /***********************************|****************************************/
  317.  
  318. void TDialogWindow::HideWindow ()
  319. {
  320.     fPosedModally = false;
  321.  
  322.     if ( fDialogWindow )
  323.     {
  324.         ::HideWindow ( fDialogWindow );
  325.         SetPort ( fDialogWindow );
  326.         SetDefaultWindowInformation ( fDialogWindow, fDialogID );
  327.     }
  328. }
  329.  
  330. /***********************************|****************************************/
  331.  
  332. static Handle GetDItemHandle ( DialogPtr dP, short whichItem )
  333. {
  334.     short itemKind;
  335.     Handle itemHandle;
  336.     Rect itemRect;
  337.     
  338.     GetDItem ( dP, whichItem, & itemKind, & itemHandle, & itemRect );
  339.  
  340.     return itemHandle;
  341. }
  342.     
  343. /***********************************|****************************************/
  344.  
  345. static void SetItemText ( DialogPtr dP, short whichItem, unsigned char * item )
  346. {
  347.     SetIText ( GetDItemHandle( dP, whichItem), item );
  348. }
  349.  
  350. /***********************************|****************************************/
  351.  
  352. static void SetItemText ( DialogPtr dP, short whichItem, char * item )
  353. {
  354.     CStr255    itemStr255 = item;
  355.     
  356.     SetIText ( GetDItemHandle( dP, whichItem), itemStr255 );
  357. }
  358.  
  359. /***********************************|****************************************/
  360.  
  361. void TDialogWindow::SetItemText ( short whichItem, CStr255 item )
  362. {
  363.     CStr255    itemStr255 = item;
  364.     
  365.     SetIText ( GetDItemHandle( fDialogWindow, whichItem), itemStr255 );
  366. }
  367.  
  368. /***********************************|****************************************/
  369.  
  370. void TDialogWindow::SetItemText ( short whichItem, Str255 item )
  371. {
  372.     SetIText ( GetDItemHandle( fDialogWindow, whichItem), item );
  373. }
  374.  
  375. /***********************************|****************************************/
  376.  
  377. void TDialogWindow::SetTextItem ( short whichItem, const CStr255& itemName )
  378. {
  379.     if (( 1 <= whichItem ) && ( whichItem <= fStringItemsCount ) )
  380.         SetIText ( GetDItemHandle( fDialogWindow, fStringItemNumbers[whichItem] ), itemName );
  381. }
  382.  
  383. /***********************************|****************************************/
  384.  
  385. void TDialogWindow::SetTextItem ( short whichItem, short stringItemID )
  386. {
  387.     Str255    value;
  388.     
  389.     if (( 1 <= whichItem ) && ( whichItem <= fStringItemsCount ) )
  390.     {
  391.         if ( stringItemID > 0 )
  392.             GetIndString ( value, fStringsSTRPoundID,  stringItemID );
  393.         else
  394.             value[0] = 0;
  395.         SetIText ( GetDItemHandle( fDialogWindow, fStringItemNumbers[whichItem] ), value );
  396.     }
  397. }
  398.  
  399. /***********************************|****************************************/
  400.  
  401. void TDialogWindow::GetTextItem ( short whichItem, CStr255& itemValue )
  402. {
  403.     Str255 value = "\p";
  404.     
  405.     if ((1 <= whichItem ) && ( whichItem <= fStringItemsCount ))
  406.         GetIText ( GetDItemHandle( fDialogWindow, fStringItemNumbers[whichItem]), value );
  407.     
  408.     itemValue = value;
  409. }
  410.  
  411. /***********************************|****************************************/
  412.  
  413. void TDialogWindow::DrawUserItem ( short i )
  414. {
  415.     //    Do nothing
  416. }
  417.  
  418. /***********************************|****************************************/
  419.  
  420. Boolean TDialogWindow::HandleEvent ( EventRecord & event )
  421. {    
  422.     Boolean        result = false;
  423.     
  424.     //    If we don't have a window, we don't need events.
  425.     if ( ! fDialogWindow )
  426.         return false;
  427.     
  428.     //    Invisible windows don't get events.
  429.     if ( !( (WindowPeek) fDialogWindow)->visible )
  430.         return false;
  431.         
  432.     switch ( event.what )
  433.     {
  434.         case mouseDown:
  435.         {
  436.             Point where = event.where;
  437.             WindowPtr    windowPointedTo;
  438.             short windowPart = FindWindow(where, &windowPointedTo);
  439.             
  440.             if ( (windowPointedTo == fDialogWindow))
  441.             {
  442.                 HandleMouseDown ( event, windowPart  );
  443.                 result = true;
  444.             }
  445.             else if ( IsModalWindow ( fDialogWindow ) && ( windowPointedTo != fDialogWindow ) )
  446.             {
  447.                 SysBeep ( 60 );
  448.                 result = true;
  449.             }
  450.         }
  451.         break;
  452.         
  453.         case nullEvent:
  454.             if ( FrontWindow() == fDialogWindow )
  455.             {    short itemHit;
  456.                 WindowPtr windowPointedTo;
  457.                 
  458.                 DialogSelect ( & event, & windowPointedTo, & itemHit );
  459.                 result = false;
  460.             }
  461.             break;
  462.  
  463.         case keyDown:
  464.         case keyUp:
  465.             if ( FrontWindow() == fDialogWindow )
  466.             {    short itemHit;
  467.                 WindowPtr windowPointedTo;
  468.                 
  469.                 result = DialogSelect ( & event, & windowPointedTo, & itemHit );
  470.             }
  471.             break;
  472.  
  473.         case activateEvt:
  474.         case updateEvt:
  475.             if (WindowPtr(event.message) == fDialogWindow)
  476.             {
  477.                 short itemHit;
  478.                 WindowPtr windowPointedTo;
  479.                 
  480.                 SetPort ( fDialogWindow );
  481.                 for ( unsigned short i = 1 ; i <= fUserItemsCount ; ++ i )
  482.                     DrawUserItem ( i );
  483.                 result = DialogSelect ( & event, & windowPointedTo, & itemHit );
  484.             }
  485.             break;
  486.     }
  487.     
  488.     return result;
  489. }
  490.  
  491. /***********************************|****************************************/
  492.  
  493. void TDialogWindow::HandleMouseDown (EventRecord& event, short where )
  494. {    GrafPtr        savePort;
  495.     Point         pt = (Point) event.where;
  496.     
  497.     GetPort(&savePort);
  498.     SetPort ( fDialogWindow );
  499.     
  500.     switch (where) {
  501.         case inDrag:
  502.         {
  503.             Rect draggingRect;
  504.             
  505.             draggingRect.top = qd.screenBits.bounds.top;
  506.             draggingRect.left = qd.screenBits.bounds.left;
  507.             draggingRect.bottom = qd.screenBits.bounds.bottom - 4;
  508.             draggingRect.right = qd.screenBits.bounds.right - 4;
  509.             
  510.             DragWindow(fDialogWindow, pt, &draggingRect);
  511.             
  512.             SetPort ( fDialogWindow );
  513.             SetDefaultWindowInformation ( fDialogWindow, fDialogID );
  514.             break;
  515.         }
  516.         
  517.         case inGrow:
  518.             break;
  519.             
  520.         case inGoAway:
  521.             if (TrackGoAway( fDialogWindow, pt))
  522.                 HideWindow( );
  523.             break;
  524.             
  525.         case inContent:
  526.         {
  527.             if (fDialogWindow == FrontWindow())
  528.             {    
  529.                 DialogPtr tempDialog;
  530.                 short itemHit;
  531.                 if ( DialogSelect ( &event, & tempDialog, & itemHit ) )
  532.                 {
  533.                     //    If it's a button that's been pressed, then call HandleButtonPress()
  534.                     for ( unsigned short i = 1; i <= fButtonItemsCount; ++i )
  535.                         if ( fButtonItemNumbers [ i ] == itemHit )
  536.                         {
  537.                             HandleButtonPress ( i );
  538.                             break;
  539.                         }
  540.                 }
  541.                 
  542.             }
  543.             else
  544.                 ::SelectWindow( fDialogWindow );
  545.                 
  546.             break;            
  547.         }
  548.     }
  549.  
  550.     SetPort(savePort);
  551. }
  552.  
  553. /***********************************|****************************************/
  554.  
  555. void TDialogWindow::HandleButtonPress ( short whichButton )
  556. {
  557.     if ( ( whichButton == 1 ) && ( fButtonItemsCount >= 1 ) && ( fButtonItemNumbers[1] == 1 ) )
  558.     {
  559.         fPosedModally = false;
  560.         fItemWhichDismissedDialog = 1;
  561.         return;
  562.     };
  563.     
  564.     if ( ( whichButton == 2 ) && ( fButtonItemsCount >= 2 ) && ( fButtonItemNumbers[2] == 2 ) )
  565.     {
  566.         fPosedModally = false;
  567.         fItemWhichDismissedDialog = 2;
  568.         return;
  569.     };
  570. }
  571.  
  572. /***********************************|****************************************/
  573.  
  574. void TDialogWindow::SetButtonTitle ( short whichButton, Str255 buttonTitle )
  575. {
  576.     if ( ( whichButton >= 1 ) && ( whichButton <= fButtonItemsCount ) )
  577.     {
  578.         SetCTitle ( (ControlHandle) GetDItemHandle ( fDialogWindow, fButtonItemNumbers[whichButton] ), buttonTitle );
  579.     }
  580. }
  581.  
  582. /***********************************|****************************************/
  583.  
  584. short TDialogWindow::PoseModally ( )
  585. {
  586.     fPosedModally = true;
  587.     
  588.     while ( fPosedModally )
  589.         TYield();
  590.         
  591.     return fItemWhichDismissedDialog;
  592. }
  593.  
  594. /***********************************|****************************************/
  595.